/*
    日志性能测试
*/
#include "../logs/logging.h"
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>


void test_performance(const std::string &logger_name, size_t thread_count, size_t msg_count, size_t msg_len)
{
    // 1.获取日志器
    logging::logger::s_ptr logger = logging::getLogger(logger_name);
    // 2.组织指定日志消息长度
    std::string msg(msg_len - 1, 'a'); // 留一个字节给换行
    // 3.创建指定数量的线程
    std::vector<std::thread> threads;
    size_t per_msg_count_by_thread = msg_count / thread_count;
    std::vector<double> waste(thread_count);
    for(int i=0; i<thread_count; i++) {
        threads.emplace_back([&, i](){
            // 4.开始计时
            auto start = std::chrono::high_resolution_clock::now();
            // 5.进行写日志
            for(int j=0; j<per_msg_count_by_thread; j++) {
                logger->debug("%s", msg);
            }
            // 6.结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> diff = end - start;
            waste[i] = diff.count();
            std::cout << "thread-" << i << ", 输出总量：" << per_msg_count_by_thread << ", 耗时" << waste[i] << "s" << std::endl;
        });
    }

    for(int i=0; i<thread_count; i++) threads[i].join();

    // 7.计算总耗时
    double sum_waste = waste[0];
    for(auto t : waste) sum_waste = std::max(sum_waste, t);
    size_t msg_per_sec = msg_count / sum_waste; // 每秒多少条
    size_t size_per_sec = (msg_count * msg_len) / (sum_waste * 1024 ); // 每秒多少kb

    // 8.结果打印
    std::cout << "\t总耗时: " << sum_waste << "s" << std::endl;
    std::cout << "\t每秒打印日志条数: " << msg_per_sec << "条" << std::endl;
    std::cout << "\t每秒打印多少字节: " << size_per_sec << "KB" << std::endl;
}

void single_thread_sync()
{
    logging::globalLoggerBuilder llb;
    llb.buildFormatter("%m%n");
    llb.buildLimitRank(logging::logLevel::value::DEBUG);
    llb.buildLoggerName("signal-sync");
    llb.buildLoggerType(logging::loggerType::SYNC_LOGGER);
    llb.buildSinks<logging::fileSink>("./file-log/file1.log");
    logging::logger::s_ptr sync_logger = llb.build();
    test_performance(sync_logger->name(), 1, 10000000, 100);
}
void multi_thread_sync()
{
    logging::globalLoggerBuilder llb;
    llb.buildFormatter("%m%n");
    llb.buildLimitRank(logging::logLevel::value::DEBUG);
    llb.buildLoggerName("multi-sync");
    llb.buildLoggerType(logging::loggerType::SYNC_LOGGER);
    llb.buildSinks<logging::fileSink>("./file-log/file2.log");
    logging::logger::s_ptr sync_logger = llb.build();
    test_performance(sync_logger->name(), 5, 10000000, 100);
}
void single_thread_async()
{

    logging::globalLoggerBuilder llb;
    llb.buildEnableUnsafe();
    llb.buildFormatter("%m%n");
    llb.buildLimitRank(logging::logLevel::value::DEBUG);
    llb.buildLoggerName("signal-async");
    llb.buildLoggerType(logging::loggerType::ASYNC_LOGGER);
    llb.buildSinks<logging::fileSink>("./file-log/file3.log");
    logging::logger::s_ptr async_logger = llb.build();
    test_performance(async_logger->name(), 1, 10000000, 100);
}
void multi_thread_async()
{
    logging::globalLoggerBuilder llb;
    llb.buildFormatter("%m%n");
    llb.buildEnableUnsafe();
    llb.buildLimitRank(logging::logLevel::value::DEBUG);
    llb.buildLoggerName("multi-async");
    llb.buildLoggerType(logging::loggerType::ASYNC_LOGGER);
    llb.buildSinks<logging::fileSink>("./file-log/file4.log");
    logging::logger::s_ptr async_logger = llb.build();
    test_performance(async_logger->name(), 5, 10000000, 100);
}


int main()
{
    //std::cout << "---------------single_thrad_sync---------------" << std::endl;
    //single_thread_sync();
    //std::cout << "---------------end of single_thread_sync---------------" << std::endl << std::endl;

    //std::cout << "---------------multi_thrad_sync---------------" << std::endl;
    //multi_thread_sync();
    //std::cout << "---------------end of multi_thread_sync---------------" << std::endl << std::endl;

    //std::cout << "---------------single_thrad_async---------------" << std::endl;
    //single_thread_async();
    //std::cout << "---------------end of single_thread_async---------------" << std::endl << std::endl;

   std::cout << "---------------multi_thrad_async---------------" << std::endl;
   multi_thread_async();
   std::cout << "---------------end of multi_thread_async---------------" << std::endl << std::endl;
    return 0;
}

//---------------single_thrad_sync---------------
//thread-0, 输出总量：10000000, 耗时8.37571
//        总耗时: 8.37571
//        每秒打印日志条数: 1193929条
//        每秒打印多少字节: 116594KB
//---------------end of single_thread_sync---------------
//---------------single_thrad_sync---------------
//thread-0, 输出总量：10000000, 耗时8.3327
//        总耗时: 8.3327
//        每秒打印日志条数: 1200091条
//        每秒打印多少字节: 117196KB
//---------------end of single_thread_sync---------------

//---------------multi_thrad_sync---------------
//thread-2, 输出总量：2000000, 耗时6.88253
//thread-4, 输出总量：2000000, 耗时6.9416
//thread-0, 输出总量：2000000, 耗时6.96349
//thread-1, 输出总量：2000000, 耗时7.07222
//thread-3, 输出总量：2000000, 耗时7.11032
//        总耗时: 6.96349
//        每秒打印日志条数: 1436062条
//        每秒打印多少字节: 140240KB
//---------------end of multi_thread_sync---------------
//---------------multi_thrad_sync---------------
//thread-2, 输出总量：2000000, 耗时6.60523
//thread-3, 输出总量：2000000, 耗时6.63692
//thread-1, 输出总量：2000000, 耗时6.64449
//thread-0, 输出总量：2000000, 耗时6.69622
//thread-4, 输出总量：2000000, 耗时6.70937
//        总耗时: 6.70937
//        每秒打印日志条数: 1490451条
//        每秒打印多少字节: 145551KB
//---------------end of multi_thread_sync---------------

//---------------single_thrad_async---------------
//thread-0, 输出总量：10000000, 耗时12.7019
//        总耗时: 12.7019
//        每秒打印日志条数: 787284条
//        每秒打印多少字节: 76883KB
//---------------end of single_thread_async---------------
//---------------single_thrad_async---------------
//thread-0, 输出总量：10000000, 耗时12.731
//        总耗时: 12.731
//        每秒打印日志条数: 785487条
//        每秒打印多少字节: 76707KB
//---------------end of single_thread_async---------------

//---------------multi_thrad_async---------------
//thread-1, 输出总量：2000000, 耗时10.3618
//thread-4, 输出总量：2000000, 耗时10.5111
//thread-3, 输出总量：2000000, 耗时10.6796
//thread-2, 输出总量：2000000, 耗时10.7359
//thread-0, 输出总量：2000000, 耗时10.7384
//        总耗时: 10.7384
//        每秒打印日志条数: 931233条
//        每秒打印多少字节: 90940KB
//---------------end of multi_thread_async---------------
//---------------multi_thrad_async---------------
//thread-3, 输出总量：2000000, 耗时9.89662
//thread-2, 输出总量：2000000, 耗时10.0791
//thread-4, 输出总量：2000000, 耗时10.0967
//thread-0, 输出总量：2000000, 耗时10.1221
//thread-1, 输出总量：2000000, 耗时10.1463
//        总耗时: 10.1463
//        每秒打印日志条数: 985578条
//        每秒打印多少字节: 96247KB
//---------------end of multi_thread_async---------------